<template>
  <div>
    <!--这种就是直接绑定了父组件props的属性，双向改变数据了。不好。-->
    <!--<input type="text" v-model="modelValue.keyword" :placeholder="modelValue.placeholder" />-->

    <!--没有提函数，每次都要写一遍-->
    <!--<input type="text" v-model="selfData.keyword" :placeholder="selfData.placeholder" />-->

    <!--提函数出去，封装了-->
    <input type="text" v-model="userData.keyword" :placeholder="userData.placeholder" />
  </div>
</template>
<script setup lang="ts">
import { useVModel } from '@views/props/single-props-update/useVModel.ts'

const props = defineProps(['modelValue'])

const emits = defineEmits(['update:modelValue'])

/**
 * 1. 使用computed拦截。
 *  a.改变整个对象；
 *  b.改变属性：那么get还得再次拦截。
 *
 * 2. 每次这么写太麻烦，提成函数。
 *
 * 3. vueuse中 useVModel的实现逻辑就是这个。
 */
const selfData = computed({
  get() {
    // return props.modelValue

    // 可以返回一个代理，在代理里面可以拦截：
    return new Proxy(props.modelValue, {
      // 方式1：
      /*get(target,key){
        return target[key]
      },
      set(target,key,val){
        target[key]= val
        return true
      },*/
      get(target, key, receiver) {
        return Reflect.get(target, key, receiver)
      },
      set(target, key, val) {
        console.log('内部set方法：', target, key, val)
        // 此时不该是修改操作，而是emits事件
        // target[key]= val

        // 原有对象，把相应的key替换掉即可。
        emits('update:modelValue', { ...target, [key]:val})
        return true
      },
    })
  },
  set(val) {
    // 只有修改selfData才会触发。如果是修改selfData的属性，不会触发的。。。。
    console.log('computed set方法')
    emits('update:modelValue', val)
  },
})

const userData = useVModel(props,'modelValue',emits)
</script>
<style scoped></style>
